package ij.plugin;

import ij.*;
import ij.plugin.filter.PlugInFilter;
import ij.process.*;
import ij.gui.*;
import ij.measure.*;
import java.awt.*;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.Vector;

/** ................ */
public class Mereotopologie2D implements PlugIn {
	ImagePlus imp;
	int nbTotalObject=0;
	Vector<Integer> nbObject;
	double [][] tabPixCommun;
	double [][] tabPourcentage1;
	double [][] tabPourcentage2;
	ArrayList[] tab1;
	ArrayList[] tab2;

	ArrayList<ArrayList[]> alAllObjects=new ArrayList<ArrayList[]>();
	public void run(String str) {

		int ids []= WindowManager.getIDList();
		Vector<ImageProcessor> StackImage=new Vector<ImageProcessor>();
		nbObject=new Vector<Integer>();
		if(ids.length>=2){
			int j=0;
			for (int i = 0; i < ids.length; i++) {
				ImagePlus imp=WindowManager.getImage(ids[i]);
				ImageProcessor ipp=imp.getProcessor();
				if(ipp instanceof ShortProcessor){
					//**StackImage.add(new ImagePlus(""+j++, ipp));
					StackImage.add(ipp);
					alAllObjects.add(ExtractObjects(ipp));

				}
			}
		//**}
		tab1=alAllObjects.get(0);
		tab2=alAllObjects.get(1);
		Vector<PixelContact> v=getSubForImages(StackImage.get(0), StackImage.get(1));
		ConstructTableForContact(v);
		
		
		ResultsTable rtb=new ResultsTable();
		rtb.incrementCounter();
		for (int i = 1; i < nbObject.get(0); i++) {
				rtb.addValue("obj"+i, tab1[i].size());
		}
		rtb.incrementCounter();
		for (int i = 1; i < nbObject.get(1); i++) {
				rtb.addValue("obj"+i, tab2[i].size());
		}
		rtb.show("Nombre de pixels par object pour chaque image");
		
		
	}else  IJ.error("Ressources", "Nombre d'images insuffisant, min=2 (16 bit) ");
		
	/*	ResultsTable rt=new ResultsTable();
		for (int i = 1; i < nbObject.get(1); i++) {
			rt.incrementCounter();
			for (int j = 1; j < nbObject.get(0); j++) {

				rt.addValue("obj"+j, tabPixCommun[j][i]);
			}
		}

		rt.show("Mereologie");*/

		
		
		ResultsTable rt1=new ResultsTable();
		for (int i = 1; i < nbObject.get(1); i++) {
			rt1.incrementCounter();
			for (int j = 1; j < nbObject.get(0); j++) {

				rt1.addValue("obj"+j, tabPourcentage1[j][i]);
			}
		}

		rt1.show("Pourcentage de contact entre les objects / 2");
		
		ResultsTable rt2=new ResultsTable();
		for (int i = 1; i < nbObject.get(1); i++) {
			rt2.incrementCounter();
			for (int j = 1; j < nbObject.get(0); j++) {

				rt2.addValue("obj"+j, tabPourcentage2[j][i]);
			}
		}

		rt2.show("Pourcentage de contact entre les objects / 1");


	}
	private ArrayList[] ExtractObjects(ImageProcessor ip) {
		short pixels[]=(short[]) ip.getPixels();
		int number=getNumberObject(ip);
		nbTotalObject=nbTotalObject+number;
		nbObject.add(number+1);
		ArrayList<PixelObject> [] tabObjects=new ArrayList[number+1];
		for (int i = 0; i < tabObjects.length; i++) {
			tabObjects[i]=new ArrayList<PixelObject>();
		}

		for (int i = 0; i < pixels.length; i++) {
			int val=pixels[i];
			if(val!=0){
				tabObjects[val].add(new PixelObject(i,val));
			}
		}
	
		return tabObjects;
	}
	private int getNumberObject(ImageProcessor ip){
		short pixels[]=(short[]) ip.getPixels();
		int max=0;
		for (int i = 0; i < pixels.length; i++) {
			int val=pixels[i];
			if(val>max)
				max=val;
		}
		return max;
	}

	private Vector<PixelContact> getSubForImages(ImageProcessor ip1,ImageProcessor ip2){
		short pixels1[]=(short[]) ip1.getPixels();
		short pixels2[]=(short[]) ip2.getPixels();
		Vector<PixelContact> v=new Vector<PixelContact>();
		for (int i = 0; i < pixels1.length; i++) {
			int val=pixels1[i];
			int val2=pixels2[i];
			if(val-val2!=val){
				v.add(new PixelContact(i, val,val2));
			}
		}
		return v;
	}
	private void ConstructTableForContact(Vector<PixelContact> v){
		int size1=nbObject.get(0);
		int size2=nbObject.get(1);
		tabPixCommun=new double[size1][size2];
		tabPourcentage1=new double[size1][size2];
		tabPourcentage2=new double[size1][size2];
		
		int i=0;
		while(i<v.size()){
			PixelContact p=v.get(i);
			int val1=p.getValue1();
			int val2=p.getValue2();
			tabPixCommun[val1][val2]=tabPixCommun[val1][val2]+1;
			i++;
		}
		
		
		
		
		
		for (int j = 1; j < size2; j++) {
			for (int j2 = 1; j2 < size1; j2++) {
				tabPourcentage1[j2][j]=(tabPixCommun[j2][j]/tab1[j2].size())*100;
			}
		}
		
		for (int j = 1; j < size1; j++) {
			for (int j2 = 1; j2 < size2; j2++) {
				tabPourcentage2[j][j2]=(tabPixCommun[j][j2]/tab2[j2].size())*100;
			}
		}
		
		

	}
}
class PixelObject{
	int coord,value;
	PixelObject(int coord,int value){
		this.coord=coord;
		this.value=value;
	}
	int getCoord(){
		return coord;
	}

	int getValue(){
		return value;
	}
}

class PixelContact{
	int coord,valOrig,val2;
	public PixelContact(int coord,int valOrig,int valCont) {
		this.coord=coord;
		this.valOrig=valOrig;
		this.val2=valCont;
	}
	int getCoord(){
		return coord;
	}

	int getValue1(){
		return valOrig;
	}
	int getValue2(){
		return val2;
	}
}